package com.alipay.sofa.award.endpoint.filter;

import com.alibaba.common.lang.StringUtil;
import com.alipay.sofa.award.biz.service.facade.UserInfoFacade;
import com.alipay.sofa.award.common.dal.dataobject.UserInfo;
import com.alipay.sofa.award.endpoint.constants.HeaderKeyConstants;
import com.alipay.sofa.award.endpoint.holder.AlipayMiniProgramUserHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.container.*;
import javax.ws.rs.core.Cookie;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.Map;

/**
 * AlipayMiniProgramAuthFilter
 *
 * @author yangguanchao
 * @since 2018/09/05
 */
@Provider
@PreMatching
public class AlipayMiniProgramAuthFilter implements ContainerRequestFilter, ContainerResponseFilter {

    private static final Logger logger = LoggerFactory.getLogger(AlipayMiniProgramAuthFilter.class);

    @Autowired
    private UserInfoFacade      userInfoFacade;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        //clear old auth user
        AlipayMiniProgramUserHolder.remove();
        //ignore auth
        if (this.skipFilter(requestContext)) {
            return;
        }
        //accessToken
        String accessToken = this.getValueByHeaderKey(requestContext,
            HeaderKeyConstants.ACCESS_TOKEN_KEY);
        //userId
        String userId = this.getValueByHeaderKey(requestContext, HeaderKeyConstants.USER_ID_KEY);
        if (StringUtil.isBlank(userId)) {
            logger.error("Get current user info error! Because userId is blank!");
            throw new RuntimeException("Get current user info error! Because userId is blank!");
        }
        UserInfo userInfo = this.userInfoFacade.selectByUserId(userId);
        if (userInfo == null) {
            logger.error("Get current user info from cache error! userId = " + userId);
            throw new RuntimeException("Get current user info from cache error! userId = " + userId);
        }
        AlipayMiniProgramUserHolder.setUserInfo(userInfo);
    }

    @Override
    public void filter(ContainerRequestContext requestContext,
                       ContainerResponseContext responseContext) throws IOException {
        //clear login
        AlipayMiniProgramUserHolder.remove();
    }

    private boolean skipFilter(ContainerRequestContext ctx) {
        String uriPath = ctx.getUriInfo().getPath();
        if (uriPath.startsWith("/openapi/") || uriPath.startsWith("/publicapi/")) {
            //openapi publicapi ignore authentication
            return true;
        }
        return false;
    }

    private String getValueByHeaderKey(ContainerRequestContext context, String httpHeaderKey) {
        String source = "";
        String httpHeaderValue = context.getHeaderString(httpHeaderKey);
        if (StringUtil.isBlank(httpHeaderValue)) {
            Map<String, Cookie> cookies = context.getCookies();
            if (cookies != null && cookies.containsKey(httpHeaderKey)) {
                httpHeaderValue = context.getCookies().get(httpHeaderKey).getValue();
                source = "cookie";
            }
        } else {
            source = "http header";
        }
        logger.debug("source={} key={} value={}", source, httpHeaderKey, httpHeaderValue);
        return httpHeaderValue;
    }
}
